package com.suixun.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.authority.common.MD5Util;
import com.suixun.Constants;
import com.suixun.dao.OpTeacherMapper;
import com.suixun.dao.SchoolinfoMapper;
import com.suixun.dao.StdPeopleinfoMapper;
import com.suixun.dao.StdTeacherInfoMapper;
import com.suixun.dao.model.PageGrid;
import com.suixun.dao.model.PageQueryModel;
import com.suixun.entity.Schoolinfo;
import com.suixun.entity.SchoolinfoExample;
import com.suixun.entity.StdPeopleinfo;
import com.suixun.entity.StdPeopleinfoExample;
import com.suixun.entity.StdTeacherInfo;
import com.suixun.entity.StdTeacherInfoExample;
import com.suixun.entity.ext.ExtTeacherInfo;
import com.suixun.entity.page.PageModel;
import com.suixun.service.TeacherService;
import com.suixun.service.common.CommonService;
import com.suixun.util.BeanUtil;
import com.suixun.util.Constant;
import com.suixun.util.ExcelUtil;
import com.suixun.util.HttpUtil;
import com.suixun.util.StringUtil;
import com.suixun.vo.TeacherVO;
@Service
public class TeacherServiceImpl implements TeacherService {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	@Resource
	private CommonService commonService;
	@Resource
	private SchoolinfoMapper schoolinfoMapper;
	@Resource
	private OpTeacherMapper opTeacherMapper;
	@Resource
	private StdPeopleinfoMapper stdPeopleinfoMapper;
	@Resource
	private StdTeacherInfoMapper stdTeacherInfoMapper;
	/**
	 * 分页获取教师信息
	 */
	@Override
	public PageModel<TeacherVO> getTeachersPage(TeacherVO teacherVo) {
		PageModel<TeacherVO> pageModel = new PageModel<>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("telephone", teacherVo.getTelephone());
		map.put("schoolid", teacherVo.getSchoolid());
		PageQueryModel pqm = new PageQueryModel(teacherVo.getPagenumber(),teacherVo.getPagecount(), "a.createtime", "desc");
		pqm.setQueryParam(map);
		PageGrid pageGrid = this.commonService.pageForObject("OpPeopleExtendSql.getTeachersPage", pqm);
		if (pageGrid == null || pageGrid.getRows().size() == 0) {
			return pageModel;
		}
		BeanUtil<ExtTeacherInfo> beanUtil = new BeanUtil<ExtTeacherInfo>();
		List<ExtTeacherInfo> ents = null;
		try {
            ents = beanUtil.ListMap2JavaBean(pageGrid.getRows(), ExtTeacherInfo.class);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
		List<TeacherVO> list = new ArrayList<>();
		if (ents != null && ents.size() > 0) {
			TeacherVO teacher = null;
			for (ExtTeacherInfo peopleTemp : ents) {
				teacher = new TeacherVO();
				teacher.setSchoolname(peopleTemp.getSchoolname());
				teacher.setClassname(peopleTemp.getClassname());
				teacher.setTeacherid(peopleTemp.getId());
				teacher.setTeachername(peopleTemp.getTeachername());
				teacher.setTelephone(peopleTemp.getTelephone());
				teacher.setCount(peopleTemp.getCount());
				list.add(teacher);
			}
			pageModel.setPagesize(teacherVo.getPagecount());
			pageModel.setTotlerows(pageGrid.getRecords());
			pageModel.setTotlepage(pageGrid.getRecords());
			pageModel.setCurrentpage(pageGrid.getPage());
		}
		pageModel.setQueryresult(list);
		return pageModel;
	}
	
	/**
	 * 导入教师信息
	 * @throws Exception 
	 */
	@Override
	@Transactional
	public Object importTeachers(HSSFWorkbook wb) throws Exception {
		
		//校验合法性
		String[] tableHead = {Constant.Excel.GRADE,Constant.Excel.TEACHERNAME,Constant.Excel.TELEPHONE,
				Constant.Excel.SCHOOL,Constant.Excel.CARD_SEND_COUNT};
		String[] excelTemplate = {Constant.Excel.TELEPHONE};
		String checkExcel = ExcelUtil.checkExcel(wb,tableHead,excelTemplate,true);
		if (!Constant.TRUE.equals(checkExcel)) {
             return checkExcel;
        }
		
		Map<String,String> tableMap = new HashMap<>();
        tableMap.put("classname", Constant.Excel.GRADE);
        tableMap.put("teachername", Constant.Excel.TEACHERNAME);
        tableMap.put("telephone", Constant.Excel.TELEPHONE);
        tableMap.put("schoolname", Constant.Excel.SCHOOL);
        tableMap.put("count", Constant.Excel.CARD_SEND_COUNT);
        ExcelUtil excelUtil = new ExcelUtil();
        List<ExtTeacherInfo> teacherLists = excelUtil.getExcelValue(tableMap,wb,ExtTeacherInfo.class);
        String checkImport = checkImportDatas(teacherLists);
		if (!Constant.TRUE.equals(checkImport)) {
			return checkImport;
		}
		//获取重复数据
		List<ExtTeacherInfo> repeatTeachers = getRepeatTeachers(teacherLists);
		List<ExtTeacherInfo> unRepeatTeachers = null;
		if (repeatTeachers.size() > 0) {
			unRepeatTeachers = getUnRepeatTeachers(teacherLists,repeatTeachers);
			for (ExtTeacherInfo teacher : unRepeatTeachers) {
				//获取schoolid
				teacher.setSchoolid(getSchoolByName(teacher.getSchoolname()).getId());
			}
			operationStdTeacherInfo(teacherLists);
			operationStdPeopleInfo(unRepeatTeachers);
			return repeatTeachers;
		}
		
		for (ExtTeacherInfo teacher : teacherLists) {
			//获取schoolid
			teacher.setSchoolid(getSchoolByName(teacher.getSchoolname()).getId());
		}
		operationStdTeacherInfo(teacherLists);
		operationStdPeopleInfo(teacherLists);
		return Constant.SUCCESS;
	}
	
	private void operationStdTeacherInfo(List<ExtTeacherInfo> teacherLists) {
		//查看std_teacherinfo表中是否存在当前班主任数据且已被删除，若存在，则修改信息并修改状态
		updateDeletedTeachersInStdTeacherInfo(getDeletedTeachersInStdTeacherInfo(teacherLists));
		List<ExtTeacherInfo> teachers = getTeachersNotInStdTeacherInfo(teacherLists);
		if (teachers.size() > 0) {
			Map<String,Object> map = new HashMap<>();
			map.put("teacherlist", teachers);
			opTeacherMapper.addTeachers(map);
		}
	}
	
	private List<ExtTeacherInfo> getTeachersNotInStdTeacherInfo(List<ExtTeacherInfo> teacherLists){
		List<ExtTeacherInfo> teachers = new ArrayList<>();
		if (teacherLists.size() > 0) {
			StdTeacherInfoExample stdTeacherInfoExample = null;
			List<StdTeacherInfo> stdTeacherList = null;
			for (ExtTeacherInfo teacher : teacherLists) {
				stdTeacherInfoExample = new StdTeacherInfoExample();
				stdTeacherInfoExample.createCriteria().andTelephoneEqualTo(teacher.getTelephone());
				stdTeacherList = stdTeacherInfoMapper.selectByExample(stdTeacherInfoExample);
				if (stdTeacherList == null || stdTeacherList.size() == 0) {
					teachers.add(teacher);
				}
			}
		}
		return teachers;
	}
	
	private void updateDeletedTeachersInStdTeacherInfo(List<ExtTeacherInfo> deletedTeachers) {
		if (deletedTeachers.size() > 0) {
			StdTeacherInfo stdTeacherInfo = null;
			StdTeacherInfoExample stdTeacherInfoExample = null;
			for (ExtTeacherInfo teacher : deletedTeachers) {
				stdTeacherInfo = new StdTeacherInfo();
				stdTeacherInfo.setTeachername(teacher.getTeachername());
				stdTeacherInfo.setClassname(teacher.getClassname());
				stdTeacherInfo.setSchoolid(teacher.getSchoolid());
				stdTeacherInfo.setCount(teacher.getCount());
				stdTeacherInfo.setIsdeleted(false);
				stdTeacherInfoExample = new StdTeacherInfoExample();
				stdTeacherInfoExample.createCriteria().andTelephoneEqualTo(teacher.getTelephone());
				stdTeacherInfoMapper.updateByExampleSelective(stdTeacherInfo, stdTeacherInfoExample);
			}
		}
	}
	
	private List<ExtTeacherInfo> getDeletedTeachersInStdTeacherInfo(List<ExtTeacherInfo> teacherLists) {
		List<ExtTeacherInfo> teachers = new ArrayList<>();
		if (teacherLists.size() > 0) {
			StdTeacherInfoExample stdTeacherInfoExample = null;
			List<StdTeacherInfo> stdTeacherList = null;
			for (ExtTeacherInfo teacher : teacherLists) {
				stdTeacherInfoExample = new StdTeacherInfoExample();
				stdTeacherInfoExample.createCriteria().andTelephoneEqualTo(teacher.getTelephone()).andIsdeletedEqualTo(true);
				stdTeacherList = stdTeacherInfoMapper.selectByExample(stdTeacherInfoExample);
				if (stdTeacherList != null && stdTeacherList.size() > 0) {
					teachers.add(teacher);
				}
			}
		}
		return teachers;
	}
	
	private void operationStdPeopleInfo(List<ExtTeacherInfo> teacherLists) {
		//查看std_peopleinfo表中是否存在当前班主任数据，若存在，则修改信息并修改状态(若为删除状态，则修改为未删除)
		updateTeachersInStdPeopleInfo(getTeachersInStdPeopleInfo(teacherLists));
		//查看std_peopleinfo表中是否存在当前班主任数据，若不存在，则新增
		List<ExtTeacherInfo> notInStdPeopleInfoLists = getTeachersNotInStdPeopleInfo(teacherLists);
		insertNotInStdPeopeInfoList(notInStdPeopleInfoLists);
	}
	
	private void insertNotInStdPeopeInfoList(List<ExtTeacherInfo> notInStdPeopleInfoLists) {
		if (notInStdPeopleInfoLists.size() > 0) {
			for (ExtTeacherInfo teacher : notInStdPeopleInfoLists) {
				teacher.setPassword(MD5Util.MD5("123456").toLowerCase());
			}
			Map<String,Object> map = new HashMap<>();
			map.put("teacherlist", notInStdPeopleInfoLists);
			opTeacherMapper.addTeachersInStdPeopeinfo(map);
		}
	}
	
	private void updateTeachersInStdPeopleInfo(List<ExtTeacherInfo> teachers) {
		if (teachers.size() > 0) {
			StdPeopleinfo stdPeopleInfo = null;
			StdPeopleinfo peopleTemp = null;
			StdPeopleinfoExample stdPeopleinfoExample = null;
			for (ExtTeacherInfo teacher : teachers) {
				stdPeopleInfo = new StdPeopleinfo();
				//判断当前老师是否已被删除，若被删除，则赋予初始密码
				peopleTemp = getPeopleByTel(teacher.getTelephone());
				if (peopleTemp != null && peopleTemp.getIsdeleted()) {
					stdPeopleInfo.setIsdeleted(false);
					stdPeopleInfo.setPassword(MD5Util.MD5("123456").toLowerCase());
				}
				stdPeopleInfo.setPeoplename(teacher.getTeachername());
				stdPeopleInfo.setClassname(teacher.getClassname());
				stdPeopleInfo.setSchoolid(teacher.getSchoolid());
				stdPeopleinfoExample = new StdPeopleinfoExample();
				stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(teacher.getTelephone());
				stdPeopleinfoMapper.updateByExampleSelective(stdPeopleInfo, stdPeopleinfoExample);
			}
		}
	}
	
	private StdPeopleinfo getPeopleByTel(String telephone) {
		StdPeopleinfoExample stdPeopleinfoExample = new StdPeopleinfoExample();
		stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(telephone);
		List<StdPeopleinfo> peopleList = stdPeopleinfoMapper.selectByExample(stdPeopleinfoExample);
		if (peopleList.size() == 0) {
			return null;
		}else {
			return peopleList.get(0);
		}
	}
	
	private List<ExtTeacherInfo> getTeachersInStdPeopleInfo(List<ExtTeacherInfo> teacherLists) {
		List<ExtTeacherInfo> teachers = new ArrayList<>();
		if (teacherLists.size() > 0) {
			StdPeopleinfoExample stdPeopleinfoExample = null;
			List<StdPeopleinfo> peopleList = null;
			for (ExtTeacherInfo teacher : teacherLists) {
				stdPeopleinfoExample = new StdPeopleinfoExample();
				stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(teacher.getTelephone());
				peopleList = stdPeopleinfoMapper.selectByExample(stdPeopleinfoExample);
				if (peopleList != null && peopleList.size() > 0) {
					teachers.add(teacher);
				}
			}
		}
		return teachers;
	}
	
	private List<ExtTeacherInfo> getTeachersNotInStdPeopleInfo(List<ExtTeacherInfo> teacherLists){
		List<ExtTeacherInfo> teachers = new ArrayList<>();
		if (teacherLists.size() > 0) {
			StdPeopleinfoExample stdPeopleinfoExample = null;
			List<StdPeopleinfo> peopleList = null;
			for (ExtTeacherInfo teacher : teacherLists) {
				stdPeopleinfoExample = new StdPeopleinfoExample();
				stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(teacher.getTelephone());
				peopleList = stdPeopleinfoMapper.selectByExample(stdPeopleinfoExample);
				if (peopleList == null || peopleList.size() == 0) {
					teachers.add(teacher);
				}
			}
		}
		return teachers;
	}
	
	private List<ExtTeacherInfo> getUnRepeatTeachers(List<ExtTeacherInfo> teacherLists,
			List<ExtTeacherInfo> repeatTeachers) {
		List<ExtTeacherInfo> unRepeatTeachers = new ArrayList<>();
		if (repeatTeachers.size() > 0) {
			for (ExtTeacherInfo teacher : teacherLists) {
				boolean isRepeat = false;
				for (ExtTeacherInfo repeatTeacher : repeatTeachers) {
					if (teacher.getTelephone().equals(repeatTeacher.getTelephone())) {
						isRepeat = true;
						break;
					}
				}
				if (!isRepeat) {
					unRepeatTeachers.add(teacher);
				}
			}
		}
		return unRepeatTeachers;
	}
	
	private List<ExtTeacherInfo> getRepeatTeachers(List<ExtTeacherInfo> teacherLists) {
		List<ExtTeacherInfo> repeatTeachers = new ArrayList<>();
		if (teacherLists != null && teacherLists.size() > 0) {
			for (ExtTeacherInfo teacherInfo : teacherLists) {
				StdTeacherInfo teacher = getTeacherByTel(teacherInfo.getTelephone());
				if (teacher != null) {
					repeatTeachers.add(teacherInfo);
				}
			}
		}
		return repeatTeachers;
	}
	
	private StdTeacherInfo getTeacherByTel(String teacherTel) {
		StdTeacherInfoExample stdTeacherInfoExample = new StdTeacherInfoExample();
		stdTeacherInfoExample.createCriteria().andTelephoneEqualTo(teacherTel).andIsdeletedEqualTo(false);
		List<StdTeacherInfo> teacherList = stdTeacherInfoMapper.selectByExample(stdTeacherInfoExample);
		if (teacherList.size() > 0) {
			return teacherList.get(0);
		}
		return null;
	}
	
	private String checkImportDatas(List<ExtTeacherInfo> teacherLists) {
		if (teacherLists != null && teacherLists.size() > 0) {
			for (int i = 0 ; i < teacherLists.size() ; i ++) {
				//检测学校是否存在
				if (getSchoolByName(teacherLists.get(i).getSchoolname()) == null) {
					return String.format("第%d行学校不存在", i+2);
				}
			}
		}
		return Constant.TRUE;
	}
	
	private Schoolinfo getSchoolByName(String schoolName) {
		SchoolinfoExample schoolinfoExample = new SchoolinfoExample();
		schoolinfoExample.createCriteria().andSchoolnameEqualTo(schoolName);
		List<Schoolinfo> schoolList = schoolinfoMapper.selectByExample(schoolinfoExample);
		if (schoolList.size() > 0) {
			return schoolList.get(0);
		}
		return null;
	}
	
	@Override
	@Transactional
	public String editTeacher(TeacherVO teacher) {
		String checkTeacher = checkTeacher(teacher);
		if (!Constant.TRUE.equals(checkTeacher)) {
			return checkTeacher;
		}
		if ("1".equals(String.valueOf(teacher.getIsdelete()))) {
			deleteTeacher(teacher.getTeacherid());
		}else {
			updateTeacher(teacher);
		}
		if (StringUtil.isNotEmpty(teacher.getTelephone())) {
			flushCache(teacher.getTeacherid(),teacher.getTelephone());
		}
		return Constant.SUCCESS;
	}
	
	private void updateTeacher(TeacherVO teacher) {
		//修改std_peopleinfo表
		StdTeacherInfo stdTeacherInfo = stdTeacherInfoMapper.selectByPrimaryKey(teacher.getTeacherid());
		StdPeopleinfo stdPeopleinfo = new StdPeopleinfo();
		StdPeopleinfoExample stdPeopleinfoExample = new StdPeopleinfoExample();
		stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(stdTeacherInfo.getTelephone()).andIsdeletedEqualTo(false);
		stdPeopleinfo.setUpdatetime(new Date());
		stdPeopleinfo.setPeopletel(stdTeacherInfo.getTelephone());
		stdPeopleinfo.setClassname(teacher.getClassname());
		stdPeopleinfo.setSchoolid(teacher.getSchoolid());
		stdPeopleinfo.setPeoplename(teacher.getTeachername());
		stdPeopleinfoMapper.updateByExampleSelective(stdPeopleinfo, stdPeopleinfoExample);
		//修改std_teacherinfo表
		StdTeacherInfo teacherInfo = new StdTeacherInfo();
		teacherInfo.setClassname(teacher.getClassname());
		teacherInfo.setCount(teacher.getCount());
		teacherInfo.setUpdatetime(new Date());
		teacherInfo.setSchoolid(teacher.getSchoolid());
		teacherInfo.setTeachername(teacher.getTeachername());
		teacherInfo.setTelephone(teacher.getTelephone());
		teacherInfo.setId(teacher.getTeacherid());
		stdTeacherInfoMapper.updateByPrimaryKeySelective(teacherInfo);
	}
	
	private void deleteTeacher(Integer teacherId) {
		StdTeacherInfo teacherInfo = new StdTeacherInfo();
		teacherInfo.setIsdeleted(true);
		teacherInfo.setUpdatetime(new Date());
		teacherInfo.setId(teacherId);
		stdTeacherInfoMapper.updateByPrimaryKeySelective(teacherInfo);
		//逻辑删除std_peopeleinfo表数据
		StdTeacherInfo stdTeacherInfo = stdTeacherInfoMapper.selectByPrimaryKey(teacherId);
		StdPeopleinfo stdPeopleinfo = new StdPeopleinfo();
		StdPeopleinfoExample stdPeopleinfoExample = new StdPeopleinfoExample();
		stdPeopleinfoExample.createCriteria().andPeopletelEqualTo(stdTeacherInfo.getTelephone()).andIsdeletedEqualTo(false);
		stdPeopleinfo.setIsdeleted(true);
		stdPeopleinfo.setUpdatetime(new Date());
		stdPeopleinfo.setPeopletel(stdTeacherInfo.getTelephone());
		stdPeopleinfoMapper.updateByExampleSelective(stdPeopleinfo, stdPeopleinfoExample);
	}

	private String checkTeacher(TeacherVO teacher) {
		if (teacher == null || teacher.getTeacherid() == null) {
			return "教师信息不能为空";
		}
		//判断教师id是否存在
		if (teacher.getTeacherid() != null) {
			StdTeacherInfoExample stdTeacherInfoExample = new StdTeacherInfoExample();
			stdTeacherInfoExample.createCriteria().andIdEqualTo(teacher.getTeacherid()).andIsdeletedEqualTo(false);
			List<StdTeacherInfo> teacherList = stdTeacherInfoMapper.selectByExample(stdTeacherInfoExample);
			if (teacherList.size() == 0) {
				return "教师id不存在";
			}
		}
		
		if (teacher.getSchoolid() != null) {
			Schoolinfo schoolinfo = schoolinfoMapper.selectByPrimaryKey(teacher.getSchoolid());
			if (schoolinfo == null) {
				return "学校不存在";
			}
		}
		
		if (StringUtil.isNotEmpty(teacher.getTelephone())) {
			StdTeacherInfo teacherInfo = getTeacherByTel(teacher.getTelephone());
			if (teacherInfo != null && teacherInfo.getId() != teacher.getTeacherid()) {
				return "手机号码已存在";
			}
		}
		return Constant.TRUE;
	}
	
	private void flushCache(Integer userid,String telphone) {
		String param = new StringBuffer().append("userid=").append(userid).append("&telephone=")
				.append(telphone).toString();
		String url;
		try {
			url = new StringBuffer().append(Constants.getApiUrl()).append(Constant.API.UPDATE_PEOPLE_TEL).toString();
			//刷新缓存
			HttpUtil.sendGet(url,param);
		} catch (IOException e) {
		}
	}
}
